﻿
INLINE VOID AlphaBlend32LevelSSE(LPCWORD, LPWORD, LPCBYTE);

//////////////////////////////////////////////////////////////////////////

// TODO: 考虑未来加入64位支持（使用64位通用寄存器，也许可以提高性能）
INLINE VOID AlphaBlend32LevelSSE(LPCWORD src, LPWORD dest, LPCBYTE alpha)
{
	// mm4 = THREETHREE (0003000300030003h)
	// mm5 = COLORMASK (07E0F81F07E0F81Fh)

	// 公式 dest = (src - dest) * alpha / 32 + dest
	// 一次同时计算2个像素
	__asm
	{
		// 一次性装载2个APLHA到mm7
		mov			esi, alpha
		mov			cx, [esi]
		jcxz		quit
		mov			esi, src
		mov			edi, dest
		movd		mm7, ecx		// ....xxAa

		// 分组扩展ALPHA
		punpcklbw	mm7, mm7		// xxxxAAaa
		pxor		mm0, mm0
		punpcklbw	mm7, mm0		// .A.A.a.a
		paddw		mm7, mm4		// ALPHA误差补正
		psrlw		mm7, 3			// 只保留32级ALPHA

		// 分别一次性装载源和目标的2个像素到mm0和mm1
		movd		mm0, [esi]		// [......][RGBrgb]
		movd		mm1, [edi]		// [......][RGBrgb]

		// 分组扩展像素
		punpcklwd	mm0, mm0		// [RGBRGB][rgbrgb]
		pand		mm0, mm5		// [.G.R.B][.g.r.b]
		punpcklwd	mm1, mm1		// [RGBRGB][rgbrgb]
		pand		mm1, mm5		// [.G.R.B][.g.r.b]

		// 混色计算（从SSE开始终于支持16位无符号乘法了，仅这一点就有性能提升）
		psubd		mm0, mm1		// mm0 = src - dest
		movq		mm2, mm0
		pmullw		mm0, mm7		// [Gx.xBx][gx.xbx]
		pmulhuw		mm2, mm7		// [.....R][.....r]
		pslld		mm2, 16			// [..R...][..r...]
		paddd		mm0, mm2		// [GxRxBx][gxrxbx]
		psrld		mm0, 5			// [.GxRxB][.gxrxb]
		paddd		mm0, mm1		// + dest
		pand		mm0, mm5		// [.G.R.B][.g.r.b]

		// 恢复像素
		pshufw		mm1, mm0, 0b1h	// [R.B.G.][r.b.g.]
		por			mm1, mm0		// [RGBRGB][rgbrgb]
		pshufw		mm0, mm1, 0d8h	// [RGBrgb][RGBrgb]

		// 保存结果
		movd		[edi], mm0

quit:
	}
}

//////////////////////////////////////////////////////////////////////////
